<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>数学练习</title>
    <style>
        :root {
            --primary-color: #4CAF50;
            --primary-hover: #45a049;
            --background-color: #f8f9fa;
            --border-color: #e0e0e0;
            --text-color: #333;
            --shadow-color: rgba(0, 0, 0, 0.1);
        }

        body {
            font-family: 'Segoe UI', Arial, sans-serif;
            max-width: 900px;
            margin: 0 auto;
            padding: 30px 20px;
            background-color: var(--background-color);
            color: var(--text-color);
            line-height: 1.6;
        }

        .container {
            background-color: white;
            padding: 30px;
            border-radius: 16px;
            box-shadow: 0 4px 20px var(--shadow-color);
            transition: transform 0.3s ease;
        }

        .container:hover {
            transform: translateY(-2px);
        }

        .settings {
            margin-bottom: 30px;
            padding: 20px;
            border: 2px solid var(--border-color);
            border-radius: 12px;
            background-color: #ffffff;
            box-shadow: inset 0 2px 4px var(--shadow-color);
        }

        .problem-display {
            font-size: 32px;
            margin: 30px 0;
            text-align: center;
            padding: 20px;
            background-color: #f8f9fa;
            border-radius: 12px;
            box-shadow: inset 0 2px 4px var(--shadow-color);
            transition: all 0.3s ease;
        }

        .controls {
            text-align: center;
            margin: 25px 0;
        }

        button {
            padding: 12px 24px;
            margin: 8px;
            border: none;
            border-radius: 8px;
            background-color: var(--primary-color);
            color: white;
            cursor: pointer;
            font-size: 16px;
            font-weight: 500;
            transition: all 0.3s ease;
            box-shadow: 0 2px 4px var(--shadow-color);
        }

        button:hover {
            background-color: var(--primary-hover);
            transform: translateY(-2px);
            box-shadow: 0 4px 8px var(--shadow-color);
        }

        button:disabled {
            background-color: #cccccc;
            cursor: not-allowed;
            transform: none;
            box-shadow: none;
        }

        input[type="text"] {
            width: 120px;
            padding: 10px;
            margin: 8px;
            border: 2px solid var(--border-color);
            border-radius: 8px;
            font-size: 16px;
            transition: all 0.3s ease;
            box-shadow: inset 0 2px 4px var(--shadow-color);
        }

        input[type="text"]:focus {
            border-color: var(--primary-color);
            outline: none;
            box-shadow: 0 0 0 3px rgba(76, 175, 80, 0.2);
        }

        .stats {
            margin-top: 30px;
            padding: 20px;
            background-color: #ffffff;
            border-radius: 12px;
            box-shadow: 0 2px 8px var(--shadow-color);
            transition: all 0.3s ease;
        }

        .stats:hover {
            transform: translateY(-2px);
        }

        .checkbox-group {
            margin: 15px 0;
            display: flex;
            flex-wrap: wrap;
            gap: 10px;
        }

        .checkbox-group label {
            margin-right: 20px;
            display: flex;
            align-items: center;
            cursor: pointer;
        }

        input[type="checkbox"] {
            margin-right: 8px;
            width: 18px;
            height: 18px;
            cursor: pointer;
        }

        @media (max-width: 768px) {
            body {
                padding: 15px;
            }

            .container {
                padding: 20px;
            }

            .problem-display {
                font-size: 24px;
            }

            input[type="text"] {
                width: 100px;
            }
        }
    </style>
</head>

<body>
    <div class="container">
        <h1 style="text-align: center;">数学练习</h1>

        <div class="settings">
            <h3>练习设置</h3>
            <div>
                <label>题目数量：</label>
                <input type="text" id="problemCount" value="10" pattern="\d+" inputmode="numeric">
            </div>

            <div class="checkbox-group">
                <label>运算类型：</label>
                <label><input type="checkbox" value="+" checked> 加法</label>
                <label><input type="checkbox" value="-" checked> 减法</label>
                <label><input type="checkbox" value="*" checked> 乘法</label>
                <label><input type="checkbox" value="/" checked> 除法</label>
            </div>

            <div>
                <label>第一个数的范围：</label>
                <input type="text" id="minNum1" value="0" placeholder="最小值" pattern="-?\d+" inputmode="numeric">
                <span>至</span>
                <input type="text" id="maxNum1" value="100" placeholder="最大值" pattern="-?\d+" inputmode="numeric">
            </div>

            <div>
                <label>第二个数的范围：</label>
                <input type="text" id="minNum2" value="0" placeholder="最小值" pattern="-?\d+" inputmode="numeric">
                <span>至</span>
                <input type="text" id="maxNum2" value="100" placeholder="最大值" pattern="-?\d+" inputmode="numeric">
            </div>

            <div>
                <label>结果范围：</label>
                <input type="text" id="minResult" value="0" placeholder="最小值" pattern="-?\d+" inputmode="numeric">
                <span>至</span>
                <input type="text" id="maxResult" value="100" placeholder="最大值" pattern="-?\d+" inputmode="numeric">
            </div>

            <div class="checkbox-group">
                <label><input type="checkbox" id="allowNegative"> 允许负数和零</label>
            </div>
        </div>

        <div class="controls">
            <button id="startBtn">开始练习</button>
            <button id="submitBtn" disabled>提交答案</button>
        </div>

        <div class="problem-display" id="problemDisplay">
            准备开始练习
        </div>

        <div class="controls">
            <input type="text" id="answer" pattern="-?\d+" inputmode="numeric" disabled>
        </div>

        <div class="stats">
            <p>用时：<span id="timer">0</span> 秒</p>
            <p>进度：<span id="progress">0</span>/<span id="total">0</span></p>
            <p>正确率：<span id="accuracy">0</span>%</p>
        </div>
    </div>

    <script>
        let currentProblem = null;
        let problems = [];
        let currentIndex = 0;
        let correctCount = 0;
        let startTime = 0;
        let timerInterval;

        // 获取DOM元素
        const startBtn = document.getElementById('startBtn');
        const submitBtn = document.getElementById('submitBtn');
        const problemDisplay = document.getElementById('problemDisplay');
        const answerInput = document.getElementById('answer');
        const timerDisplay = document.getElementById('timer');
        const progressDisplay = document.getElementById('progress');
        const totalDisplay = document.getElementById('total');
        const accuracyDisplay = document.getElementById('accuracy');

        // 生成随机数
        function getRandomInt(min, max) {
            return Math.floor(Math.random() * (max - min + 1)) + min;
        }

        // 生成题目
        function generateProblem() {
            const operators = Array.from(document.querySelectorAll('input[type="checkbox"]:checked'))
                .slice(0, 4) // 先截取前4个元素 
                .map(checkbox => checkbox.value);

            if (operators.length === 0) {
                alert('请至少选择一种运算类型！');
                return null;
            }

            const minNum1 = parseInt(document.getElementById('minNum1').value);
            const maxNum1 = parseInt(document.getElementById('maxNum1').value);
            const minNum2 = parseInt(document.getElementById('minNum2').value);
            const maxNum2 = parseInt(document.getElementById('maxNum2').value);
            const minResult = parseInt(document.getElementById('minResult').value);
            const maxResult = parseInt(document.getElementById('maxResult').value);
            const operator = operators[Math.floor(Math.random() * operators.length)];
            let num1, num2, result;

            do {
                switch (operator) {
                    case '+':
                        num1 = getRandomInt(minNum1, maxNum1);
                        num2 = getRandomInt(minNum2, maxNum2);
                        result = num1 + num2;
                        break;
                    case '-':
                        num1 = getRandomInt(minNum1, maxNum1);
                        num2 = getRandomInt(minNum2, maxNum2);
                        result = num1 - num2;
                        break;
                    case '*':
                        num1 = getRandomInt(minNum1, maxNum1);
                        num2 = getRandomInt(minNum2, maxNum2);
                        result = num1 * num2;
                        break;
                    case '/':
                        // 生成除数，确保不为0
                        do {
                            num2 = getRandomInt(minNum2, maxNum2);
                        } while (num2 === 0);
                        
                        // 生成被除数，确保能整除
                        do {
                            num1 = getRandomInt(minNum1, maxNum1);
                        } while (num1 % num2 !== 0);
                        
                        result = num1 / num2;
                        break;
                }
            } while (result < minResult || result > maxResult);

            return {
                num1,
                num2,
                operator,
                result
            };
        }

        // 生成所有题目
        function generateAllProblems() {
            const count = parseInt(document.getElementById('problemCount').value);
            const minResult = parseInt(document.getElementById('minResult').value);
            const maxResult = parseInt(document.getElementById('maxResult').value);

            // 验证输入值的合法性
            const allowNegative = document.getElementById('allowNegative').checked;
            if (!allowNegative && minResult < 0) {
                alert('未启用负数选项时，最小值不能小于0！');
                return null;
            }

            if (minResult >= maxResult) {
                alert('最小值必须小于最大值！');
                return null;
            }

            const problems = [];
            const usedProblems = new Set();

            while (problems.length < count) {
                const problem = generateProblem();
                if (!problem) return null;

                const problemString = `${problem.num1}${problem.operator}${problem.num2}`;
                if (!usedProblems.has(problemString)) {
                    problems.push(problem);
                    usedProblems.add(problemString);
                }
            }

            return problems;
        }

        // 显示当前题目
        function displayProblem() {
            const problem = problems[currentIndex];
            let operatorDisplay = problem.operator;
            if (operatorDisplay === '*') operatorDisplay = '×';
            if (operatorDisplay === '/') operatorDisplay = '÷';

            problemDisplay.textContent = `${problem.num1} ${operatorDisplay} ${problem.num2} = ?`;
            progressDisplay.textContent = currentIndex + 1;
            totalDisplay.textContent = problems.length;
        }

        // 更新计时器
        function updateTimer() {
            const currentTime = Math.floor((Date.now() - startTime) / 1000);
            timerDisplay.textContent = currentTime;
        }

        // 开始练习
        startBtn.addEventListener('click', () => {
            problems = generateAllProblems();
            if (!problems) return;

            currentIndex = 0;
            correctCount = 0;
            startTime = Date.now();
            timerInterval = setInterval(updateTimer, 1000);

            displayProblem();
            startBtn.disabled = true;
            submitBtn.disabled = false;
            answerInput.disabled = false;
            answerInput.value = '';
            answerInput.focus();

            // 重置统计信息
            accuracyDisplay.textContent = '0';
        });

        // 提交答案
        submitBtn.addEventListener('click', () => {
            const userAnswer = parseInt(answerInput.value);
            if (isNaN(userAnswer)) {
                alert('请输入有效的数字！');
                return;
            }

            const problem = problems[currentIndex];
            if (userAnswer === problem.result) {
                correctCount++;
            }

            currentIndex++;
            answerInput.value = '';

            // 更新正确率
            const accuracy = Math.round((correctCount / currentIndex) * 100);
            accuracyDisplay.textContent = accuracy;

            if (currentIndex < problems.length) {
                displayProblem();
                answerInput.focus();
            } else {
                // 练习结束
                clearInterval(timerInterval);
                const totalTime = Math.floor((Date.now() - startTime) / 1000);
                const finalAccuracy = Math.round((correctCount / problems.length) * 100);

                setTimeout(() => {
                    alert(`练习完成！\n用时：${totalTime} 秒\n正确率：${finalAccuracy}%`);
                    startBtn.disabled = false;
                    submitBtn.disabled = true;
                    answerInput.disabled = true;
                    problemDisplay.textContent = '准备开始练习';
                }, 100);
            }
        });

        // 支持回车键提交
        answerInput.addEventListener('keypress', (e) => {
            if (e.key === 'Enter' && !submitBtn.disabled) {
                submitBtn.click();
            }
        });

        // 添加输入框的实时验证
        const minResultInput = document.getElementById('minResult');
        const maxResultInput = document.getElementById('maxResult');

        function validateNumberInput(input, allowNegative) {
            let value = input.value;
            const cursorPosition = input.selectionStart;
            const hasNegativeSign = value.startsWith('-');

            if (!allowNegative) {
                value = value.replace(/\D/g, '');
            } else {
                // 保留第一个负号，去掉其他非数字字符
                if (hasNegativeSign) {
                    value = '-' + value.substring(1).replace(/\D/g, '');
                } else {
                    value = value.replace(/\D/g, '');
                }
            }

            // 处理空值和单个负号的情况
            if (value === '' || value === '-') {
                input.value = value;
                return;
            }

            // 设置最小值限制
            const numValue = parseInt(value);
            if (!allowNegative && numValue < 0) {
                value = '0';
            }

            input.value = value;

            // 恢复光标位置
            const newPosition = hasNegativeSign ? Math.min(cursorPosition, value.length) : cursorPosition;
            input.setSelectionRange(newPosition, newPosition);
        }

        function handleNumberRangeInput(minInput, maxInput, defaultMin, defaultMax) {
            const allowNegative = document.getElementById('allowNegative').checked;
            validateNumberInput(minInput, allowNegative);
            validateNumberInput(maxInput, allowNegative);

            let minValue = minInput.value;
            let maxValue = maxInput.value;

            if (minValue === '' || minValue === '-' || maxValue === '' || maxValue === '-') return;

            minValue = parseInt(minValue || defaultMin);
            maxValue = parseInt(maxValue || defaultMax);

            // 检查最大值为0的情况
            if (maxValue === 0) {
                if (!allowNegative) {
                    alert('最大值不能为零，请开启负数模式！');
                    maxInput.value = '1';
                    maxValue = 1;
                } else {
                    // 在允许负数模式下，如果最小值也为0，则将其改为-1
                    if (minValue === 0) {
                        minInput.value = '-1';
                        minValue = -1;
                    }
                }
            }

            if (!allowNegative && minValue < 0) {
                minInput.value = '0';
            } else if (minValue >= maxValue) {
                minInput.value = (maxValue - 1).toString();
            }

            if (maxValue <= minValue) {
                maxInput.value = (minValue + 1).toString();
            }
        }

        function handleMinResultInput() {
            handleNumberRangeInput(minResultInput, maxResultInput, '0', '100');
        }

        function handleMaxResultInput() {
            handleNumberRangeInput(minResultInput, maxResultInput, '0', '100');
        }

        function handleMinNum1Input() {
            handleNumberRangeInput(document.getElementById('minNum1'), document.getElementById('maxNum1'), '0', '100');
        }

        function handleMaxNum1Input() {
            handleNumberRangeInput(document.getElementById('minNum1'), document.getElementById('maxNum1'), '0', '100');
        }

        function handleMinNum2Input() {
            handleNumberRangeInput(document.getElementById('minNum2'), document.getElementById('maxNum2'), '0', '100');
        }

        function handleMaxNum2Input() {
            handleNumberRangeInput(document.getElementById('minNum2'), document.getElementById('maxNum2'), '0', '100');
        }

        // 绑定所有范围输入框的事件处理
        minResultInput.addEventListener('input', handleMinResultInput);
        maxResultInput.addEventListener('input', handleMaxResultInput);
        document.getElementById('minNum1').addEventListener('input', handleMinNum1Input);
        document.getElementById('maxNum1').addEventListener('input', handleMaxNum1Input);
        document.getElementById('minNum2').addEventListener('input', handleMinNum2Input);
        document.getElementById('maxNum2').addEventListener('input', handleMaxNum2Input);

        // 当允许负数选项改变时重新验证所有输入
        document.getElementById('allowNegative').addEventListener('change', (e) => {
            const allowNegative = e.target.checked;
            const inputs = [
                minResultInput, maxResultInput,
                document.getElementById('minNum1'), document.getElementById('maxNum1'),
                document.getElementById('minNum2'), document.getElementById('maxNum2')
            ];
            
            inputs.forEach(input => validateNumberInput(input, allowNegative));
            handleMinResultInput();
            handleMaxResultInput();
            handleMinNum1Input();
            handleMaxNum1Input();
            handleMinNum2Input();
            handleMaxNum2Input();
        });
    </script>
</body>

</html>